import cv2
import mediapipe as mp
import time
import numpy as np

# 初始化MediaPipe组件
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_face_mesh = mp.solutions.face_mesh

# 1. 先创建窗口并配置属性（关键：必须在imshow前创建窗口）
cv2.namedWindow(
    'MediaPipe Face Detection',  # 窗口名称（需与imshow一致）
    cv2.WINDOW_NORMAL  # 窗口属性：允许手动调整大小（核心参数）
)
# 2. 设置窗口初始大小（宽x高，单位：像素）
WINDOW_WIDTH = 1200   # 自定义宽度（例如1200像素）
WINDOW_HEIGHT = 900   # 自定义高度（例如900像素）
cv2.resizeWindow('MediaPipe Face Detection', WINDOW_WIDTH, WINDOW_HEIGHT)

# 打开摄像头（800x600分辨率，与窗口大小独立）
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600)

# FPS计算（滑动窗口平均法）
FRAME_WINDOW = 10
frame_times = []
fps = 0

# 创建FaceMesh实例
face_mesh = mp_face_mesh.FaceMesh(
    max_num_faces=1,
    refine_landmarks=True,
    min_detection_confidence=0.6,
    min_tracking_confidence=0.6,
    static_image_mode=False
)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("无法获取摄像头帧，退出程序")
        break

    # 记录处理开始时间
    start_time = time.time()

    # 图像预处理（供MediaPipe使用）
    frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    frame_rgb = np.ascontiguousarray(frame_rgb)

    # 人脸检测
    results = face_mesh.process(frame_rgb)

    # 在原始帧上绘制特征点
    if results.multi_face_landmarks:
        for face_landmarks in results.multi_face_landmarks:
            mp_drawing.draw_landmarks(
                image=frame,
                landmark_list=face_landmarks,
                connections=mp_face_mesh.FACEMESH_TESSELATION,
                landmark_drawing_spec=None,
                connection_drawing_spec=mp_drawing_styles.get_default_face_mesh_tesselation_style()
            )
            mp_drawing.draw_landmarks(
                image=frame,
                landmark_list=face_landmarks,
                connections=mp_face_mesh.FACEMESH_CONTOURS,
                landmark_drawing_spec=None,
                connection_drawing_spec=mp_drawing_styles.get_default_face_mesh_contours_style()
            )

    # 翻转画面
    frame = cv2.flip(frame, 1)

    # 计算并绘制FPS
    end_time = time.time()
    frame_times.append(end_time - start_time)
    if len(frame_times) > FRAME_WINDOW:
        frame_times.pop(0)
    if frame_times:
        fps = 1 / (sum(frame_times) / len(frame_times))

    cv2.putText(
        frame,
        f"FPS: {fps:.1f}",
        (10, 30),
        cv2.FONT_HERSHEY_SIMPLEX,
        1.0,
        (0, 255, 255),
        2,
        cv2.LINE_AA
    )

    # 显示画面（窗口已提前创建并设置大小）
    cv2.imshow('MediaPipe Face Detection', frame)

    # 退出条件
    if cv2.waitKey(1) & 0xFF == 27:
        break

# 释放资源
face_mesh.close()
cap.release()
cv2.destroyAllWindows()